import track, { startTrack, stopTrack } from '../../effect/track.js';
import { reactive } from '../../func/reactive.js';
import { isObject, TrackOpTypes, RAW } from '../../utils/index.js';

const arrayInstrumentations = {};
// 重写方法
const methods = ['indexOf', 'lastIndexOf', 'includes'];
methods.forEach((method) => {
  arrayInstrumentations[method] = function (...args) {
    // 先调用原始方法
    const res = Array.prototype[method].apply(this, args);
    if (res < 0 || res === false) {
      // 如果结果为负数或false，说明原始方法返回了false
      // 则需要调用原始数组的方法来获取结果
      return Array.prototype[method].apply(this[RAW], args);
    }
    return res;
  };
});

// 重写push、pop、shift、unshift、splice方法
const mutativeMethods = ['push', 'pop', 'shift', 'unshift', 'splice'];
mutativeMethods.forEach((method) => {
  arrayInstrumentations[method] = function (...args) {
    stopTrack();
    const res = Array.prototype[method].apply(this, args);
    startTrack();
    return res;
  };
});

/**
 * 获取属性值的处理函数
 * @param {*} target 目标对象
 * @param {*} key 属性名
 * @returns {*} 属性值或原始数组
 */
export default function getHandler(target, key) {
  // 访问RAW属性时，返回原始对象
  if (key === RAW) {
    return target;
  }
  track(target, TrackOpTypes.GET, key);
  const res = Reflect.get(target, key);

  if (Array.isArray(target) && arrayInstrumentations.hasOwnProperty(key)) {
    // 如果是数组，且有重写的方法，则调用重写方法
    return arrayInstrumentations[key];
  }

  // 递归处理嵌套对象
  if (isObject(res)) {
    return reactive(res);
  }
  return res;
}
